package com.github.eclipseace.mybatis.spring;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;

/**
 * @author eclipseAce
 */
public class MapperEnhancerConfigurerRegistrar implements ImportBeanDefinitionRegistrar {
	protected void registerAnonymousBeanDefinition(BeanDefinition definition,
			BeanDefinitionRegistry registry) {
		String beanName = BeanDefinitionReaderUtils.generateBeanName(definition, registry, true);
		registry.registerBeanDefinition(beanName, definition);
	}

	@Override
	public void registerBeanDefinitions(AnnotationMetadata anMetadata, BeanDefinitionRegistry registry) {
		AnnotationAttributes attrs = AnnotationAttributes.fromMap(
				anMetadata.getAnnotationAttributes(EnableMapperEnhancer.class.getName()));
		String[] basePackages = attrs.getStringArray("basePackages");
		String[] templateLocations = attrs.getStringArray("templateLocations");
		String entityStoreRef = attrs.getString("entityStoreRef");
		String sqlSessionFactoryRef = attrs.getString("sqlSessionFactoryRef");

		BeanDefinitionBuilder mpcDefBuilder = BeanDefinitionBuilder
				.genericBeanDefinition(MapperEnhancerConfigurer.class)
				.addPropertyValue("basePackages", basePackages)
				.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
		if (!entityStoreRef.isEmpty()) {
			mpcDefBuilder.addPropertyReference("entityStore", entityStoreRef);
		}
		if (!sqlSessionFactoryRef.isEmpty()) {
			mpcDefBuilder.addPropertyReference("sqlSessionFactory", sqlSessionFactoryRef);
		}
		for (String templateLocation : templateLocations) {
			BeanDefinitionBuilder xebDefBuilder = BeanDefinitionBuilder
					.genericBeanDefinition(XmlElementBuilderFactoryBean.class)
					.addPropertyValue("location", templateLocation);
			registerAnonymousBeanDefinition(xebDefBuilder.getBeanDefinition(), registry);
		}
		registerAnonymousBeanDefinition(mpcDefBuilder.getBeanDefinition(), registry);
	}
}
